package com.qibiao.drawguess;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.app.Context;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;

public class Draw extends Component implements Component.TouchEventListener,Component.DrawTask{

    Paint mPaint = new Paint();
    Path mPath = new Path();
    Point mPrePoint = new Point();
    Point mPreCtrlPoint = new Point();

    PictureData pictureData;

    public Draw(Context context) {
        super(context);

        pictureData = new PictureData();

        InitPaint();
        IniEvt();
    }


    public String getPictureData(){
        return pictureData.saveAsString();
    }

    public void readPictureString(String picture){
        pictureData.readFromString(picture);
        drawByPictureData();
    }

    public void drawByPictureData(){
        Clear();
        invalidate();

        for(int i=0;i<pictureData.getLineCount();i++){
            ArrayList<Float> line = pictureData.getLineById(i);
            for(int p=0;p<line.size();){
                float x = line.get(p);
                p++;
                float y = line.get(p);
                p++;

                if(p == 2){
                    onNewLine(x, y);
                }else{
                    onDrawToPoint(x, y);
                }
            }
        }

        // trigger onDraw()
        invalidate();
    }

    public   void InitPaint()
    {
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(5f);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);
    }

    private  void IniEvt()
    {
        addDrawTask(this::onDraw);
        setTouchEventListener(this::onTouchEvent);
    }

    public void Clear()
    {
        mPath.reset();
        invalidate();
    }

    public void ClearData(){
        pictureData.clear();
    }

    private void onNewLine(float x, float y){
        y -= 300;
        mPath.moveTo(x, y);

        mPrePoint.position[0] = x;
        mPrePoint.position[1] = y;
        mPreCtrlPoint.position[0] = x;
        mPreCtrlPoint.position[1] = y;
    }

    private void onDrawToPoint(float x, float y){
        y -= 300;
        Point currCtrlPoint = new Point((x + mPrePoint.position[0]) / 2,
                (y + mPrePoint.position[1]) / 2);

        mPath.cubicTo(mPrePoint, mPreCtrlPoint, currCtrlPoint);

        mPreCtrlPoint.position[0] = currCtrlPoint.position[0];
        mPreCtrlPoint.position[1] = currCtrlPoint.position[1];
        mPrePoint.position[0] = x;
        mPrePoint.position[1] = y;
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        switch (touchEvent.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN: {
                MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());

                onNewLine(point.getX(), point.getY());

                // save data
                pictureData.newLine(point.getX(), point.getY());

                return true;
            }
            case TouchEvent.PRIMARY_POINT_UP:
                break;
            case TouchEvent.POINT_MOVE: {
                MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
                onDrawToPoint(point.getX(), point.getY());
                pictureData.addPoint(point.getX(), point.getY());
                invalidate();
                break;
            }
        }
        return false;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.drawPath(mPath, mPaint);
    }
}
